home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 February: Tool Chest / Dev.CD Feb 00 TC.toast / pc / what's new? / sample code / human interface toolbox / packagetool / packagetool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-02  |  9.2 KB  |  327 lines

  1. /*
  2.     file PackageTool.c
  3.     
  4.     Description:
  5.     This file contains the main event displatching code used in the PackageTool
  6.     application.
  7.     
  8.     PackageTool is an application illustrating how to create application
  9.     packages in Mac OS 9.  It provides a simple interface for converting
  10.     correctly formatted folders into packages and vice versa.
  11.  
  12.     Copyright: © 1999 by Apple Computer, Inc.
  13.     all rights reserved.
  14.     
  15.     Disclaimer:
  16.     You may incorporate this sample code into your applications without
  17.     restriction, though the sample code has been provided "AS IS" and the
  18.     responsibility for its operation is 100% yours.  However, what you are
  19.     not permitted to do is to redistribute the source as "DSC Sample Code"
  20.     after having made changes. If you're going to re-distribute the source,
  21.     we require that you make it clear in the source that the code was
  22.     descended from Apple Sample Code, but that you've made changes.
  23.     
  24.     Change History (most recent first):
  25.     10/19/99 created
  26. */
  27.  
  28. #include "PackageTool.h"
  29. #include "Utilities.h"
  30.  
  31. #include <Fonts.h>
  32. #include <Dialogs.h>
  33. #include <PLStringFuncs.h>
  34. #include <TextUtils.h>
  35. #include <Gestalt.h>
  36. #include <StdIO.h>
  37. #include <Devices.h>
  38. #include <Appearance.h>
  39. #include <Resources.h>
  40.  
  41. #include "SimplePrefs.h"
  42. #include "PackageUtils.h"
  43. #include "PackageWindow.h"
  44.  
  45.     /* application's globals */
  46. Boolean gRunning = true; /* true while the application is running, set to false to quit */
  47. Collection gPreferences = NULL; /* main preferences collection, saved in the prefs file.  */
  48.  
  49.  
  50. Collection GetCollectedPreferences(void) {
  51.     return gPreferences;
  52. }
  53.  
  54.  
  55.  
  56.  
  57. /* ResetMenus is called to reset the menus immediately before
  58.     either MenuSelect or MenuKey is called.  Here, we disable the
  59.     quit command during file copies. */
  60. static void ResetMenus(void) {
  61.     MenuHandle fileMenu;
  62.         /* get the file menu from the current menu list */
  63.     fileMenu = GetMenuHandle(mFile);
  64.         /* disable quit if we're in the middle of copying a file */
  65. }
  66.  
  67.  
  68. /* DoMenuCommand is called after either MenuSelect of MenuKey.  The
  69.     parameter rawMenuSelectResult is the result from one of these two routines. 
  70.     DoMenuCommand parses this result into its two parts, and dispatches
  71.     the menu command as appropriate. */
  72. static void DoMenuCommand(long rawMenuSelectResult) {
  73.     short menu, item;
  74.         /* decode the MenuSelect result */
  75.     menu = (rawMenuSelectResult >> 16);
  76.     if (menu == 0) return;
  77.     item = (rawMenuSelectResult & 0x0000FFFF);
  78.         /* dispatch on result */
  79.     switch (menu) {
  80.         case mApple:
  81.             if (item == iAbout) {
  82.                     /* show the about box. */
  83.                 ParamAlert(kAboutBoxAlert, NULL, NULL);
  84.             }
  85.             break;
  86.         case mFile:
  87.             if (item == iQuit) gRunning = false; /* file.quit == quit */
  88.             break;
  89.         case mEdit:
  90.             if (item == iClear) SetNewDisplay(NULL); /* edit.clear == clear the display */
  91.             break;
  92.     }
  93.         /* unhilite the menu once we're done the command */
  94.     HiliteMenu(0);
  95. }
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103. /* OpenApplication is an apple event handler called for 'open application' apple events. */
  104. static pascal OSErr OpenApplication(const AppleEvent *appleEvt, AppleEvent* reply, unsigned long refcon) {
  105.     return noErr;
  106. }
  107.  
  108. /* CloseApplication is an apple event handler called for 'close application' apple events. */
  109. static pascal OSErr CloseApplication(const AppleEvent *appleEvt, AppleEvent* reply, unsigned long refcon) {
  110.     gRunning = false;
  111.     return noErr;
  112. }
  113.  
  114.  
  115. static pascal OSErr OpenDocument(const AppleEvent *appleEvt, AppleEvent* reply, unsigned long refcon) {
  116.     OSErr err;
  117.     AEDescList documents;
  118.     long n;
  119.     FSSpec fileSpec, packageSpec;
  120.     AEKeyword keyWd;
  121.     DescType typeCd;
  122.     Size actSz;
  123.     
  124.         /* initial state */
  125.     AECreateDesc(typeNull, NULL, 0, &documents);
  126.     
  127.         /* get the open parameter */
  128.     err = AEGetParamDesc(appleEvt, keyDirectObject, typeAEList, &documents);
  129.     if (err != noErr) goto bail;
  130.     err = AECountItems(&documents, &n);
  131.     if (err != noErr) goto bail;
  132.     if (n == 0) { err = paramErr; goto bail; }
  133.     err = AEGetNthPtr(&documents, 1, typeFSS, &keyWd, &typeCd,
  134.         (Ptr) &fileSpec, sizeof(fileSpec), (actSz = sizeof(fileSpec), &actSz));
  135.     if (err != noErr) goto bail;
  136.     
  137.     if (IdentifyPackage(&fileSpec, &packageSpec))
  138.         SetNewDisplay(&fileSpec);
  139.     else if (FSSpecIsAFolder(&fileSpec))
  140.         SetNewDisplay(&fileSpec);
  141.     else SetNewDisplay(NULL);
  142.  
  143. bail:
  144.     AEDisposeDesc(&documents);
  145.     return err;
  146. }
  147.  
  148.  
  149. /* EVENT HANDLING ------------------------------------------------ */
  150.  
  151.  
  152. /* HandleNextEvent handles the event in the event record *ev dispatching
  153.     the event to appropriate routines.   */
  154. static void HandleNextEvent(EventRecord *ev) {
  155.     DialogPtr theDialog;
  156.     WindowPtr theWindow;
  157.     short itemNo;
  158.     
  159.         /* dialog pre-processing */
  160.     if (((ev->what == keyDown) || (ev->what == autoKey)) && ((ev->modifiers & cmdKey) != 0)) {
  161.         ResetMenus();
  162.         DoMenuCommand(MenuKey((char) (ev->message & charCodeMask)));
  163.     } else if (ev->what == osEvt) {
  164.         WindowPtr target;
  165.         Boolean activate;
  166.         if ( (((ev->message >> 24) & 0x0FF) == suspendResumeMessage) && ((ev->message & resumeFlag) != 0)) {
  167.             activate = true;/* switching in */
  168.         } else activate = false;
  169.         target = FrontWindow();
  170.         if (IsPackageWindow(target))
  171.             ActivatePackageWindow(target, activate);
  172.     } else if (ev->what == activateEvt) {
  173.         WindowPtr target;
  174.         target = (WindowPtr) ev->message;
  175.         if (IsPackageWindow(target))
  176.             ActivatePackageWindow(target, ((ev->modifiers & activeFlag) != 0));
  177.     }
  178.  
  179.         /* handle clicks in the dialog window */
  180.     if (IsDialogEvent(ev))
  181.         if (DialogSelect(ev, &theDialog, &itemNo)) {
  182.             if (IsPackageWindow(GetDialogWindow(theDialog)))
  183.                 HitPackageWindow(theDialog, ev, itemNo);
  184.         }
  185.  
  186.         /* clicks and apple events... */
  187.     if (ev->what == kHighLevelEvent) {
  188.         AEProcessAppleEvent(ev);
  189.     } else if (ev->what == mouseDown)
  190.         switch (FindWindow(ev->where, &theWindow)) {
  191.             
  192.                 /* menu bar clicks */
  193.             case inMenuBar:
  194.                 ResetMenus();
  195.                 DoMenuCommand(MenuSelect(ev->where));
  196.                 break;
  197.                 
  198.                 /* clicks in the close box, close the app */
  199.             case inGoAway:
  200.                 if (TrackGoAway(theWindow, ev->where)) {
  201.                     gRunning = false;
  202.                 }
  203.                 break;
  204.                 
  205.                 /* allow window drags */
  206.             case inDrag:
  207.                 if (theWindow == FrontWindow()) {
  208.                     Rect boundsRect = { -32000, -32000, 32000, 32000};
  209.                     DragWindow(theWindow, ev->where, &boundsRect);
  210.                 }
  211.                 break;
  212.         }
  213. }
  214.  
  215.  
  216.  
  217.  
  218. /* MyIdleProc is the idle procedure called by AEInteractWithUser while we are waiting
  219.     for the application to be pulled into the forground.  It simply passes the event along
  220.     to HandleNextEvent */
  221. static pascal Boolean MyIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn) {
  222.     HandleNextEvent(theEvent);
  223.     return false;
  224. }
  225.  
  226. /* ParamAlert is a general alert handling routine.  If Apple events exist, then it
  227.     calls AEInteractWithUser to ensure the application is in the forground, and then
  228.     it displays an alert after passing the s1 and s2 parameters to ParamText. */
  229. OSStatus ParamAlert(short alertID, StringPtr s1, StringPtr s2) {
  230.     AEIdleUPP theIdleUPP;
  231.     OSStatus err;
  232.     theIdleUPP = NewAEIdleProc(MyIdleProc);
  233.     if (theIdleUPP == NULL) { err = memFullErr; goto bail; }
  234.     err = AEInteractWithUser(kNoTimeOut, NULL, theIdleUPP);
  235.     if (err != noErr) goto bail;
  236.     ParamText(s1, s2, NULL, NULL);
  237.     err = Alert(alertID, NULL);
  238.     DisposeAEIdleUPP(theIdleUPP);
  239.     return err;
  240. bail:
  241.     if (theIdleUPP != NULL) DisposeAEIdleUPP(theIdleUPP);
  242.     return err;
  243. }
  244.  
  245.  
  246.  
  247.  
  248. /* main program */
  249.  
  250. int main(void) {
  251.     OSErr err;
  252.     long response;
  253.     AEEventHandlerUPP aehandler;
  254.     
  255.         /* set up the managers */
  256.     InitCursor();
  257.             
  258.     if (Gestalt('sysv', &response) != noErr) response = 0;
  259.     if (response < 0x0900) {
  260.         ParamAlert(138, NULL, NULL);
  261.         err = userCanceledErr;
  262.         goto bail;
  263.     }
  264.  
  265.     err = RegisterAppearanceClient();
  266.     if (err != noErr) goto bail;
  267.     
  268.         /* Apple event handlers */
  269.     aehandler = NewAEEventHandlerProc(OpenApplication);
  270.     if (aehandler == NULL) { err = memFullErr; goto bail; }
  271.     err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, aehandler, 0, false);
  272.     if (err != noErr) goto bail;
  273.     aehandler = NewAEEventHandlerProc(CloseApplication);
  274.     if (aehandler == NULL) { err = memFullErr; goto bail; }
  275.     err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, aehandler, 0, false);
  276.     if (err != noErr) goto bail;
  277.     aehandler = NewAEEventHandlerProc(OpenDocument);
  278.     if (aehandler == NULL) { err = memFullErr; goto bail; }
  279.     err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, aehandler, 0, false);
  280.     if (err != noErr) goto bail;
  281.  
  282.         /* get our preferences */    
  283.     gPreferences = NewCollection();
  284.     if (gPreferences == NULL) { err = memFullErr; goto bail; }
  285.     GetPreferences(kAppPrefsType, kAppCreatorType, gPreferences);
  286.  
  287.         /* ***** set up the menu bar ***** */
  288.     SetMenuBar(GetNewMBar(kMenuBarResource));
  289.     DrawMenuBar();
  290.     AppendResMenu(GetMenuHandle(mApple), 'DRVR');
  291.     
  292.         /* open the window */
  293.     err = CreatePackageWindow();
  294.     if (err != noErr) {
  295.         Str255 errStr;
  296.         NumToString(err, errStr);
  297.         ParamAlert(kOpenAppFailedAlert, errStr, NULL);
  298.     }
  299.  
  300.         /* run the main loop */
  301.     while (gRunning) {
  302.         EventRecord ev;
  303.             /* get the next event */
  304.         if ( ! WaitNextEvent(everyEvent, &ev,  GetCaretTime(), NULL) )
  305.             ev.what = nullEvent;
  306.         HandleNextEvent(&ev);
  307.     }
  308.     
  309.         /* all done */
  310.     ClosePackageWindow();
  311.     UnregisterAppearanceClient();
  312.     SavePreferences(kAppPrefsType, kAppCreatorType, "\pPackageTool Preferences", gPreferences);
  313.     DisposeCollection(gPreferences);
  314.     ExitToShell();
  315.     return 0;
  316. bail:
  317.     if (err != userCanceledErr) {
  318.         Str255 errStr;
  319.         NumToString(err, errStr);
  320.         ParamAlert(kMainFailedAlert, errStr, NULL);
  321.     }
  322.     ExitToShell();
  323.     return 1;
  324. }
  325.  
  326.  
  327.